
Criado em: 19/05/2022
Última Atualização: 26/05/2022
Análise feita por 🚀 Rafael Morais de Assis
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import random
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import warnings
warnings.filterwarnings("ignore")
import os
for dirname, _, filenames in os.walk('/kaggle/input'):
for filename in filenames:
print(os.path.join(dirname, filename))
# Configs
pd.options.display.float_format = '{:,.4f}'.format
sns.set(style="whitegrid")
sns.set_palette("Set3")
plt.style.use('seaborn')
seed = 42
np.random.seed(seed)
random.seed(seed)
df = pd.read_csv('./State of Data 2021 - Dataset.csv', low_memory=False)
def get_prefix_cols(prefix="('P9"):
"""
Retorna aas colunas do DataFrame que começam com um prefixo
"""
return [x for x in df.columns.tolist() if x.startswith(prefix)]
def df_rating_missing_data(my_df):
"""Create DataFrame with Missing Rate
"""
# get sum missing rows and filter has mising values
ms_sum = my_df.isnull().sum()
ms_sum = ms_sum.drop( ms_sum[ms_sum == 0].index )
# get percentage missing ratio and filter has mising values
ms_per = (my_df.isnull().sum() / len(my_df))
ms_per = ms_per.drop( ms_per[ms_per == 0].index)
# order by
ms_per = ms_per.sort_values(ascending=False)
ms_sum = ms_sum.sort_values(ascending=False)
# format percentage
ms_per = ms_per.apply(lambda x: '{:.3%}'.format(x))
return pd.DataFrame({'Missing Rate' : ms_per, 'Count Missing': ms_sum})
from math import floor
def insert_break_line(astring, index_point=5):
"""
Usada para por <br> em textos muitos longos, que acaba atrapalhando na visualização
"""
splited = astring.split(' ')
for i in range(floor(len(splited)/index_point)):
splited.insert(index_point * (i+1), '<br>')
return " ".join(splited).replace(' <br> ','<br>')
def pie_plot_one_feat(col, title, replaces={}, break_line=False, break_point=10):
df_col = df[col]
df_col = df_col.replace(replaces)
df_aux = df_col.value_counts().reset_index().rename(
columns={'index': 'Valor', col: 'Quantidade'})
if(break_line):
df_aux['Valor'] = df_aux['Valor'].apply(
lambda x: x if len(x.split(' ')) < break_point else insert_break_line(x) )
fig = px.pie(df_aux, values='Quantidade', names='Valor', title=title,
color_discrete_sequence=px.colors.sequential.Rainbow
)
fig.update_traces(textposition='inside', textinfo='percent+label')
fig.show()
def count_valid_values(aseries, show=False):
"""
Tem a opção de mostrar os dados caso quiser velos em print
"""
if(show):
print('unique_values =', len(aseries.unique()), end='')
print(' | count_not_nan = ', aseries.count() )
return aseries.count()
def bar_plot_many_options(adf,prefix, temp_name_col, title, true_count, replaces={}, break_line=False ):
"""
Serve somente para este notebook. Apartir da pergunta base, busca as outras colunas das respostas.
@break line: caso tiver nomes muito grandes, insere <br>
"""
df_temp = adf[get_prefix_cols(prefix=prefix)]
df_temp = df_temp.sum().reset_index()
df_temp['index'] = df_temp['index'].apply(lambda x: x.split("', '")[1].strip().replace("'",'').replace(')','',1))
df_temp = df_temp.rename(columns={'index': temp_name_col, 0: 'Quantidade'})
df_temp['Quantidade'] = df_temp['Quantidade'].apply(lambda x: int(x))
# Alter x-axis (cat-feat value)
df_temp = df_temp.replace(replaces).sort_values('Quantidade', ascending=True)
if(break_line):
df_temp[temp_name_col] = df_temp[temp_name_col].apply(
lambda x: x if len(x.split(' ')) < 10 else insert_break_line(x) )
# Porcentagem
df_temp['Porcentagem'] = round( (df_temp['Quantidade'] / true_count) * 100.0, 2)
df_temp['PorcentagemStr'] = df_temp['Porcentagem'].apply(lambda x: str(format(x, '.2f')) + '%' )
fig = px.bar(df_temp, y=temp_name_col, x='Quantidade',
color='Quantidade', hover_data=['Porcentagem'],
text="PorcentagemStr", orientation='h',
title=title, color_continuous_scale='dense'
)
if(break_line):
fig.update_layout(height=1000)
fig.show()
def plotly_number_feat_describe(df, number_col, rename_col='', title=''):
"""
Pra uma coluna numerica cria: pandas.describe, histograma e violin plot
"""
# DEFINE CONSTANTS
rename_col = number_col if not rename_col else rename_col
the_title = number_col if not title else title
# Create Table
adf = df[number_col].describe().reset_index().rename(
columns={'index': 'Statistics', number_col: rename_col})
interval = df[number_col].max() - df[number_col].min()
adf.at[1,rename_col] = round(adf.at[1,rename_col], 2) # mean
adf.at[2,rename_col] = round(adf.at[2,rename_col], 2) # std
adf = adf.append({'Statistics': 'interval', rename_col: interval },
ignore_index = True)
# CREATE SUBPLOT
fig = make_subplots(
rows=1, cols=3,
vertical_spacing=0.01,
specs=[[{"type": "table"},
{"type": "bar"},
{'type': 'violin'}]]
)
# FIG 1: PLOTLY TABLE
fig.add_trace(
go.Table(
header=dict(
values=list(adf.columns),
fill_color='rgb(100, 31, 104)',
align='left',
font=dict(color='white', size=14),
),
cells=dict(
values=[adf['Statistics'], adf[rename_col] ],
fill_color='rgb(230, 240, 240)',
align='left'),
),
row=1, col=1
)
# FIG 2 : HISTOGRAM PURE
fig.add_trace(
go.Histogram(
x=df[number_col],
marker=dict(color='rgb(120, 100, 202)'),
name='Histogram',
),
row=1, col=2
)
# FIG 3: VIOLIN PLOT
fig.add_trace(
go.Violin(
y=df[number_col],
box_visible=True,
line_color='black',
meanline_visible=True,
fillcolor='rgb(129, 180, 227)',
opacity=0.6,
x0=rename_col,
name='Violin',
), row=1, col=3
)
# FIGURE CONFIGS
fig.update_layout(
width=900, height=500,
title_text=the_title
)
fig.show()
# use print(px.colors.sequential.dense) para gerar paleta de cores
def pie_plot_one_option(prefix, temp_name_col, title, replaces={}):
df_temp = df[get_prefix_cols(prefix=prefix)]
df_temp = df_temp.sum().reset_index()
df_temp['index'] = df_temp['index'].apply(lambda x: x.split(',')[1].strip().replace("'",'')[:-1])
df_temp = df_temp.rename(columns={'index': temp_name_col, 0: 'Quantidade'})
df_temp['Quantidade'] = df_temp['Quantidade'].apply(lambda x: int(x))
df_temp = df_temp.replace(replaces).sort_values('Quantidade', ascending=True)
fig = px.pie(df_temp, values='Quantidade', names=temp_name_col, title=title,
color_discrete_sequence=px.colors.sequential.Jet
#dense[::-1]; Rainbow # full list:
)
fig.update_traces(textposition='inside', textinfo='percent+label')
fig.show()
print( df.shape[0], 'linhas |', df.shape[1], 'colunas')
df[ df.columns.tolist()[:4] ].head()
2645 linhas | 356 colunas
| ('P0', 'id') | ('P1_a ', 'Idade') | ('P1_a_a ', 'Faixa idade') | ('P1_b ', 'Genero') | |
|---|---|---|---|---|
| 0 | qkx4q0ei90wcjxnqkx4q0j3xgf0zn13s | 38.0000 | 35-39 | Masculino |
| 1 | zdl2n19yhgpnoaco6kkczdl2nwv9zwrt | 39.0000 | 35-39 | Masculino |
| 2 | vsamqp2un3q7us84mgvsams5fulsmcoh | 30.0000 | 30-34 | Masculino |
| 3 | v31ab41botodnsv31zgg4k34zzojy81l | 38.0000 | 35-39 | Feminino |
| 4 | ubhu8ntvm4xc0sfkdubhu80e973eek0k | 36.0000 | 35-39 | Masculino |
# Listar todas as colunas com alguns valores
# list_cols = df.columns.tolist()
# for el in list_cols:
# print(el)
# print(df[el].unique().tolist()[:3])
# print()
df_rating_missing_data(df)
| Missing Rate | Count Missing | |
|---|---|---|
| ('P5_b ', 'Qual oportunidade você está buscando?') | 94.064% | 2488 |
| ('P5_d ', 'Como tem sido a busca por um emprego na área de dados?') | 93.989% | 2486 |
| ('P5_c ', 'Há quanto tempo você busca uma oportunidade na área de dados?') | 93.913% | 2484 |
| ('P6_g_c ', 'AWS Deequ') | 92.136% | 2437 |
| ('P6_g_k ', 'Anomalo') | 92.136% | 2437 |
| ... | ... | ... |
| ('P2_q ', 'Atualmente qual a sua forma de trabalho?') | 10.586% | 280 |
| ('P1_i ', 'Área de Formação') | 2.420% | 64 |
| ('P1_e ', 'Estado onde mora') | 1.361% | 36 |
| ('P1_e_a ', 'uf onde mora') | 1.361% | 36 |
| ('P1_a ', 'Idade') | 1.059% | 28 |
341 rows × 2 columns
import missingno as msno
%matplotlib inline
msno.matrix(df)
<AxesSubplot:>
df_section = df[get_prefix_cols(prefix="('P1")]
display(df_rating_missing_data(df_section))
# # todas as colunas estão cehias, por isso nao aparece 0%
# msno.matrix(df_section);
| Missing Rate | Count Missing | |
|---|---|---|
| ('P1_g_b ', 'Regiao de origem') | 81.701% | 2161 |
| ('P1_i ', 'Área de Formação') | 2.420% | 64 |
| ('P1_e ', 'Estado onde mora') | 1.361% | 36 |
| ('P1_e_a ', 'uf onde mora') | 1.361% | 36 |
| ('P1_a ', 'Idade') | 1.059% | 28 |
Grandes parte da idades de quem respondeu é entre 25 á 35 anos. Mínimo de 18 e Máximo de 54
adf = df["('P1_a ', 'Idade')"].describe().reset_index()
adf
| index | ('P1_a ', 'Idade') | |
|---|---|---|
| 0 | count | 2,617.0000 |
| 1 | mean | 31.1571 |
| 2 | std | 7.1306 |
| 3 | min | 18.0000 |
| 4 | 25% | 26.0000 |
| 5 | 50% | 30.0000 |
| 6 | 75% | 35.0000 |
| 7 | max | 54.0000 |
plotly_number_feat_describe(df, "('P1_a ', 'Idade')", 'Idade', 'Estatisticas Descritivas para a Idade')
adf
| index | ('P1_a ', 'Idade') | |
|---|---|---|
| 0 | count | 2,617.0000 |
| 1 | mean | 31.1571 |
| 2 | std | 7.1306 |
| 3 | min | 18.0000 |
| 4 | 25% | 26.0000 |
| 5 | 50% | 30.0000 |
| 6 | 75% | 35.0000 |
| 7 | max | 54.0000 |
def plotly_describe_numberf_by_catf(df, number_feat, cat_feat, title=''):
title = number_feat + ' by ' + cat_feat if not title else title
# dropnan pois se houver nao conegue por as cores corretamente
# e tambem nao muda em nada, pois so faz o box de quem NAO TEM NAN
cols = [number_feat, cat_feat]
adf = df[cols].dropna(axis='index', subset=cols)
# Box Plot
fig = px.box(adf,
x=cat_feat,
y=number_feat,
color=cat_feat,
)
# Configs
fig.update_layout(
title_text=title, title_x=0.5,
)
fig.show()
plotly_describe_numberf_by_catf(df, "('P1_a ', 'Idade')", "('P2_g ', 'Nivel')", 'Idade por Nivel')
# "('P1_a ', 'Idade')"
# col="('P2_g ', 'Nivel')"
cols = ["('P2_g ', 'Nivel')", "('P1_a ', 'Idade')"]
adf = df[cols].dropna(axis='index', subset=cols)
fig = px.box(adf,
x="('P2_g ', 'Nivel')",
y="('P1_a ', 'Idade')",
color="('P2_g ', 'Nivel')",
# points="all",
title='alfa'
)
fig.update_layout(
title_text='Your title',
title_x=0.5,
# xaxis_title="X Axis Title",
# yaxis_title="Y Axis Title",
# legend_title="Legend Title",
# font=dict(
# family="Courier New, monospace",
# size=18,
# color="RebeccaPurple"
)
fig.show()
# fig = px.histogram(df, x="('P2_g ', 'Nivel')", y="('P1_a ', 'Idade')",
# color="('P2_g ', 'Nivel')",
# marginal="box", # or violin, rug
# )
# fig.show()
pie_plot_one_feat(
col="('P1_b ', 'Genero')",
title='Gênero',
)
"('P1_e ', 'Estado onde mora')",
"('P1_e_a ', 'uf onde mora')",
"('P1_e_b ', 'Regiao onde mora')",
"('P1_g_b ', 'Regiao de origem')",
"('P1_g_c ', 'Mudou de Estado?')",
pie_plot_one_feat(
col="('P1_e ', 'Estado onde mora')",
title='Estado onde mora',
)
pie_plot_one_feat(
col="('P1_g_b ', 'Regiao de origem')",
title='Mudou de Estado',
)
pie_plot_one_feat(
col="('P1_g_c ', 'Mudou de Estado?')",
title='Mudou de Estado',
replaces={0: 'Não', 1: 'Sim'},
)
pie_plot_one_feat(
col="('P1_h ', 'Nivel de Ensino')",
title='Nível de Ensino',
)
pie_plot_one_feat(
col="('P1_i ', 'Área de Formação')",
title='Área de Formação',
)
pie_plot_one_feat(
col="('P2_a ', 'Qual sua situação atual de trabalho?')",
title='Situação de Trabalho',
break_line=True,
)
pie_plot_one_feat(
col="('P2_b ', 'Setor')",
title='Setor',
)
Melhorar: Por em barras e Ordenado
pie_plot_one_feat(
col="('P2_c ', 'Numero de Funcionarios')",
title='Numero de Funcionarios',
)
pie_plot_one_feat(
col="('P2_d ', 'Gestor?')",
title='Gestor',
replaces={1:'Sim',0:'Não'}
)
pie_plot_one_feat(
col="('P2_e ', 'Cargo como Gestor')",
title='Cargo como Gestor',
)
pie_plot_one_feat(
col="('P2_f ', 'Cargo Atual')",
title='Cargo Atual'
)
pie_plot_one_feat(
col="('P2_g ', 'Nivel')",
title='Nível',
)
df_temp = df["('P2_h ', 'Faixa salarial')"].value_counts().reset_index()
df_temp = df_temp.rename(columns={'index': 'Faixa salarial', "('P2_h ', 'Faixa salarial')": "Quantidade"})
df_temp['Faixa salarial'] = df_temp['Faixa salarial'].apply(lambda x: x.replace('R$', 'RS'))
df_temp['Ordem'] = [7, 5, 6, 8, 4, 3, 9, 2, 10, 11, 12, 13, 1]
df_temp['Porcentagem'] = round( (df_temp['Quantidade'] / df_temp['Quantidade'].sum()) * 100.0, 2)
df_temp['PorcentagemStr'] = df_temp['Porcentagem'].apply(lambda x: str(format(x, '.2f')) + '%' )
df_temp = df_temp.sort_values('Ordem')
df_temp
| Faixa salarial | Quantidade | Ordem | Porcentagem | PorcentagemStr | |
|---|---|---|---|---|---|
| 12 | Menos de RS 1.000/mês | 32 | 1 | 1.3500 | 1.35% |
| 7 | de RS 1.001/mês a RS 2.000/mês | 126 | 2 | 5.3300 | 5.33% |
| 5 | de RS 2.001/mês a RS 3000/mês | 180 | 3 | 7.6100 | 7.61% |
| 4 | de RS 3.001/mês a RS 4.000/mês | 183 | 4 | 7.7400 | 7.74% |
| 1 | de RS 4.001/mês a RS 6.000/mês | 403 | 5 | 17.0400 | 17.04% |
| 2 | de RS 6.001/mês a RS 8.000/mês | 393 | 6 | 16.6200 | 16.62% |
| 0 | de RS 8.001/mês a RS 12.000/mês | 479 | 7 | 20.2500 | 20.25% |
| 3 | de RS 12.001/mês a RS 16.000/mês | 263 | 8 | 11.1200 | 11.12% |
| 6 | de RS 16.001/mês a RS 20.000/mês | 129 | 9 | 5.4500 | 5.45% |
| 8 | de RS 20.001/mês a RS 25.000/mês | 62 | 10 | 2.6200 | 2.62% |
| 9 | de RS 25.001/mês a RS 30.000/mês | 43 | 11 | 1.8200 | 1.82% |
| 10 | de RS 30.001/mês a RS 40.000/mês | 38 | 12 | 1.6100 | 1.61% |
| 11 | Acima de RS 40.001/mês | 34 | 13 | 1.4400 | 1.44% |
fig = px.bar(
df_temp, y='Quantidade', x='Faixa salarial',
color='Quantidade', hover_data=['PorcentagemStr'],
text="PorcentagemStr", title='Faixa Salarial',
color_continuous_scale='dense'
)
fig.show()
pie_plot_one_feat(
col="('P2_i ', 'Quanto tempo de experiência na área de dados você tem?')",
title='EXP na área de dados',
)
pie_plot_one_feat(
col="('P2_j ', 'Quanto tempo de experiência na área de TI/Engenharia de Software você teve antes de começar a trabalhar na área de dados?')",
title='Exp em TI antes de entrar na área de dados',
replaces={
'Não tive experiência na área de TI/Engenharia de Software antes de começar a trabalhar na área de dados':
'Não tive experiência<br>na área de TI/Engenharia de Software<br>antes de começar a trabalhar <br>na área de dados',
}
)
pie_plot_one_feat(
col="('P2_k ', 'Você está satisfeito na sua empresa atual?')",
title='Está satisfeito na sua empresa atual',
replaces={1:'Sim',0:'Não'}
)
pie_plot_one_feat(
col="('P2_m ', 'Você participou de entrevistas de emprego nos últimos 6 meses?')",
title='Você participou de entrevistas de emprego nos últimos 6 meses?',
break_line=True,
break_point=5,
)
pie_plot_one_feat(
col="('P2_n ', 'Você pretende mudar de emprego nos próximos 6 meses?')",
title='Você participou de entrevistas de emprego nos últimos 6 meses?',
break_line=True,
)
pie_plot_one_feat(
col="('P2_q ', 'Atualmente qual a sua forma de trabalho?')",
title='Forma de Trabalho',
replaces={
'Modelo híbrido flexível (o funcionário tem liberdade para escolher quando estar no escritório presencialmente)': 'Modelo hibrido flexivel',
'Modelo híbrido com dias fixos de trabalho presencial': 'Modelo hibrido com <br> dias fixo presencial'
}
)
pie_plot_one_feat(
col="('P2_r ', 'Qual a forma de trabalho ideal para você?')",
title='Qual a forma de Trabalho Ideal',
)
pie_plot_one_feat(
col="('P2_s ', 'Caso sua empresa decida pelo modelo 100% presencial qual será sua atitude?')",
title='O que fara caso a empresa adotar 100% remoto',
)
multiple_answer_col = "('P2_l ', 'Qual o principal motivo da sua insatisfação com a empresa atual?')"
bar_plot_many_options(
df,
prefix="('P2_l_",
temp_name_col='Motivo de instisfacao',
true_count=count_valid_values(df[multiple_answer_col]),
title='Principal motivo de instisfação no trabalho',
)
multiple_answer_col = "('P2_o ', 'Quais os principais critérios que você leva em consideração no momento de decidir onde trabalhar?')"
bar_plot_many_options(
df,
prefix="('P2_o_",
temp_name_col='Criterios para decidir trabalhar',
true_count=count_valid_values(df[multiple_answer_col]),
title='Principais critérios na hora de decidir onde trabalhar',
)
multiple_answer_col = "('P3_b ', 'Quais desses papéis/cargos fazem parte do time (ou chapter) de dados da sua empresa?')"
bar_plot_many_options(
df,
prefix="('P3_b_",
temp_name_col='Papeis na Equpe',
true_count=count_valid_values(df[multiple_answer_col]),
title='Papeis mais presentes na equipe de dados',
)
multiple_answer_col = "('P3_c ', 'Quais dessas responsabilidades fazem parte da sua rotina atual de trabalho como gestor?')"
bar_plot_many_options(
df,
prefix="('P3_c_",
temp_name_col='Papeis do Gestor',
true_count=count_valid_values(df[multiple_answer_col]),
title='Papeis mais cumpridos pelos gestores',
break_line=True,
)
multiple_answer_col = "('P3_d ', 'Quais são os 3 maiores desafios que você tem como gestor no atual momento?')"
bar_plot_many_options(
df,
prefix="('P3_d_",
temp_name_col='Maiores Desafios',
true_count=count_valid_values(df[multiple_answer_col]),
title='Maiores Desafios como gestor',
break_line=True,
)
Falta "('P4_a ', 'Atuacao')",
multiple_answer_col = "('P4_b ', 'Quais das fontes de dados listadas você já analisou ou processou no trabalho?')"
bar_plot_many_options(
df,
prefix="('P4_b_",
temp_name_col='Fonts Usadas',
true_count=count_valid_values(df[multiple_answer_col]),
title='Fontes de dados mais usadas pelo menos uma vez',
)
multiple_answer_col = "('P4_c ', 'Entre as fontes de dados listadas, quais você utiliza na maior parte do tempo?')"
bar_plot_many_options(
df,
prefix="('P4_c_",
temp_name_col='Fonts Usadas',
true_count=count_valid_values(df[multiple_answer_col]),
title='Fontes de dados mais usadas no trabalho',
)
multiple_answer_col = "('P4_d ', 'Quais das linguagens listadas abaixo você utiliza no trabalho?')"
bar_plot_many_options(
df,
prefix="('P4_d_",
temp_name_col='Linguagens Usadas',
true_count=count_valid_values(df[multiple_answer_col]),
title='Linguagesn mais usadas',
)
pie_plot_one_option(
prefix="('P4_e_",
temp_name_col='Linguagem mais usadas',
title='Qual a principal linguagem mais usada',
)
multiple_answer_col = "('P4_f ', 'Quais dos bancos de dados/fontes de dados listados abaixo você utiliza no trabalho?')"
bar_plot_many_options(
df,
prefix="('P4_f_",
temp_name_col='Bancos de dados usados',
true_count=count_valid_values(df[multiple_answer_col]),
title='Banco de dados mais usados',
)
multiple_answer_col = "('P4_g ', 'Quais das opções de Cloud listadas abaixo você utiliza no trabalho?')"
bar_plot_many_options(
df,
prefix="('P4_g_",
temp_name_col='Cloud usados',
true_count=count_valid_values(df[multiple_answer_col]),
title='Clouds mais usados',
)
multiple_answer_col = "('P4_h ', 'Quais as Ferramentas de Business Intelligence você utiliza no trabalho?')"
bar_plot_many_options(
df,
prefix="('P4_h_",
temp_name_col='Ferramenta de BI',
true_count=count_valid_values(df[multiple_answer_col]),
title='Ferramentas de BI mais usadas',
)
Falta Fazer aqui
multiple_answer_col = "('P6_a ', 'Quais das opções abaixo fazem parte da sua rotina no trabalho atual como engenheiro de dados?')"
bar_plot_many_options(
df,
prefix="('P6_a_",
temp_name_col='Tarefa de DataEng',
true_count=count_valid_values(df[multiple_answer_col]),
title='Tarefas de DataEng',
break_line=True
)
multiple_answer_col = "('P6_b ', 'Quais as ferramentas/tecnologias de ETL que você utiliza no trabalho como Data Engineer?')"
bar_plot_many_options(
df,
prefix="('P6_b_",
temp_name_col='ETL Tool',
true_count=count_valid_values(df[multiple_answer_col]),
title='Ferramenta de ETL mais usada',
)
multiple_answer_col = "('P6_g ', 'Quais as ferramentas de gestão de Qualidade de dados, Metadados e catálogo de dados você utiliza no trabalho?')"
bar_plot_many_options(
df,
prefix="('P6_g_",
temp_name_col='Gestão de Qualidade de Dados Tool',
true_count=count_valid_values(df[multiple_answer_col]),
title='Gestão de Qualidade de Dados mais usada',
)
multiple_answer_col = "('P6_h ', 'Em qual das opções abaixo você gasta a maior parte do seu tempo?')"
bar_plot_many_options(
df,
prefix="('P6_h_",
temp_name_col='Atividade',
true_count=count_valid_values(df[multiple_answer_col]),
title='Atividade que mais gasta tempo',
break_line=True,
)
multiple_answer_col = "('P7_a ', 'Quais das opções abaixo fazem parte da sua rotina no trabalho atual com análise de dados?')"
bar_plot_many_options(
df,
prefix="('P6_a_",
temp_name_col='Rotina de DataAnalyst',
true_count=count_valid_values(df[multiple_answer_col]),
title='Rotinas de DataAnalyst',
break_line=True,
)
multiple_answer_col = "('P7_b ', 'Quais as ferramentas/tecnologias de ETL que você utiliza no trabalho como Data Analyst?')"
bar_plot_many_options(
df,
prefix="('P7_b_",
temp_name_col='Ferramente de ETL de DataAnalyst',
true_count=count_valid_values(df[multiple_answer_col]),
title='Ferramente de ETL de DataAnalyst',
)
multiple_answer_col = "('P7_c ', 'Sua empresa utiliza alguma das ferramentas listadas para dar mais autonomia em análise de dados para as áreas de negócio?')"
bar_plot_many_options(
df,
prefix="('P7_c_",
temp_name_col='Ferramenta de Automatica de DataAnalyse',
true_count=count_valid_values(df[multiple_answer_col]),
title='Ferramenta de Automatica de DataAnalyse',
break_line=True,
)
multiple_answer_col = "('P7_d ', 'Em qual das opções abaixo você gasta a maior parte do seu tempo de trabalho?')"
bar_plot_many_options(
df,
prefix="('P7_d_",
temp_name_col='Atividade que mais gasta Tempo',
true_count=count_valid_values(df[multiple_answer_col]),
title='Atividade de DataAnalyst que mais gasta Tempo',
break_line=True,
)
multiple_answer_col = "('P8_a ', 'Quais das opções abaixo fazem parte da sua rotina no trabalho atual com ciência de dados?')"
bar_plot_many_options(
df,
prefix="('P8_a_",
temp_name_col='Atividade de DataScience',
true_count=count_valid_values(df[multiple_answer_col]),
title='Rotina de DataScientist',
break_line=True,
)
multiple_answer_col = "('P8_b ', 'Quais as técnicas e métodos listados abaixo você costuma utilizar no trabalho?')"
bar_plot_many_options(
df,
prefix="('P8_b_",
temp_name_col='Técnicas e Ferramentas de Data Science',
true_count=count_valid_values(df[multiple_answer_col]),
title='Técnicas e Ferramentas mais utilizadas DataScience',
break_line=True,
)
multiple_answer_col = "('P8_c ', 'Quais dessas tecnologias fazem parte do seu dia a dia como cientista de dados?')"
bar_plot_many_options(
df,
prefix="('P8_c_",
temp_name_col='Tecnologias de DataScience',
true_count=count_valid_values(df[multiple_answer_col]),
title='Tecnologias de DataScience',
)
multiple_answer_col = "('P8_d ', 'Em qual das opções abaixo você gasta a maior parte do seu tempo no trabalho?')"
bar_plot_many_options(
df,
prefix="('P8_d_",
temp_name_col='Atividade de DataScience',
true_count=count_valid_values(df[multiple_answer_col]),
title='Atividade de DataScience que mais gasta Tempo',
break_line=True,
)
"('P9_a ', 'Quais das iniciativas do Data Hackers que você já acessou/acompanhou?')",
"('P9_a_a ', 'Blog/Medium do Data Hackers')",
"('P9_a_b ', 'Podcast do Data Hackers')",
"('P9_a_d ', 'Newsletter Semanal')",
"('P9_a_e ', 'Canal do Slack')",
"('P9_a_f ', 'Canal do Youtube do Data Hackers')",
"('P9_a_g ', 'Ainda não conhecia o Data Hackers')"
multiple_answer_col = "('P9_a ', 'Quais das iniciativas do Data Hackers que você já acessou/acompanhou?')"
bar_plot_many_options(
df,
prefix="('P9_a_",
temp_name_col='iniciativas do Data Hackers',
true_count=count_valid_values(df[multiple_answer_col]),
title='iniciativas do Data Hackers',
)
mapping_faixa_salario = {
'Menos de R$ 1.000/mês': 1,
'de R$ 1.001/mês a R$ 2.000/mês': 2,
'de R$ 2.001/mês a R$ 3000/mês': 3,
'de R$ 3.001/mês a R$ 4.000/mês': 4,
'de R$ 4.001/mês a R$ 6.000/mês': 5,
'de R$ 6.001/mês a R$ 8.000/mês': 6,
'de R$ 8.001/mês a R$ 12.000/mês': 7,
'de R$ 12.001/mês a R$ 16.000/mês': 8,
'de R$ 16.001/mês a R$ 20.000/mês': 9,
'de R$ 20.001/mês a R$ 25.000/mês': 10,
'de R$ 25.001/mês a R$ 30.000/mês': 11,
'de R$ 30.001/mês a R$ 40.000/mês': 12,
'Acima de R$ 40.001/mês': 13,
}
mapping_faixa_salario_re = {
'Menos de RS 1.000/mês': 1,
'de RS 1.001/mês a RS 2.000/mês': 2,
'de RS 2.001/mês a RS 3000/mês': 3,
'de RS 3.001/mês a RS 4.000/mês': 4,
'de RS 4.001/mês a RS 6.000/mês': 5,
'de RS 6.001/mês a RS 8.000/mês': 6,
'de RS 8.001/mês a RS 12.000/mês': 7,
'de RS 12.001/mês a RS 16.000/mês': 8,
'de RS 16.001/mês a RS 20.000/mês': 9,
'de RS 20.001/mês a RS 25.000/mês': 10,
'de RS 25.001/mês a RS 30.000/mês': 11,
'de RS 30.001/mês a RS 40.000/mês': 12,
'Acima de RS 40.001/mês': 13,
}
sort_by_faixa_salarial = {"('P2_h ', 'Faixa salarial')": list(mapping_faixa_salario_re.keys()) }
def get_percentage_complex(df1, df_origin, col_target):
"""
Retorna a porcentage de um valor sobre o sum no dataframe original.
Eh necessario fazer manulamente pois se não tiver todas as combinaçoes de cat feats
ao fazer da forma automatica da erro. Entao, eh necessario para haver
AS COMBINAÇÇOES CAT_FEAT CUJA CONTAGEM SEJA ZERO
"""
array = []
df_sum = df_origin[col_target].value_counts().reset_index()
df_sum.columns = [col_target, 'sum']
for index, row in df1.iterrows():
if(row['count'] != 0):
v = 100 * (row['count'] / df_sum[ df_sum[col_target] == row[col_target]]['sum'].iloc[0])
else:
v = 0
array.append(v)
return array
def plotly_cat_to_cat(df, catx, cat2, title='', orderby_func=None):
"""
Amabas devem ser cat feats
orderby_func = muitas vezes a cat_feat eh ordenavel, use essa campos para designar a funcao
TEM QUE VERIFICAR QUANDO NAO TEM TODAS AS CATEGORIAS, AI DA ERRO
"""
cols = [catx, cat2]
# Faz todas as combinações dos valores unicos de cada coluna
# por conta disos, se hovuer nao houver a ocorrencia de uma dessa combinaçoes
# a sua contagem de porcentagem tem que ser feita de forma analogica
# na funcao 'get_percentage_complex'
df_temp = df.groupby(cols).size().to_frame('count').reindex(
pd.MultiIndex.from_product([df[catx].unique(), df[cat2].unique()]), fill_value = 0)
df_temp = df_temp.reset_index().dropna()
df_temp.columns = cols + ['count']
df_temp['percentage'] = get_percentage_complex(df_temp, df, catx)
df_temp['total'] = df_temp['percentage']
df_temp.columns = cols + ['Counts', 'Percentage', 'Total']
fig = px.bar(df_temp, x=catx, y=['Total'], color=cat2,
category_orders=orderby_func, hover_data=['Counts'],
text=df_temp['Percentage'].apply(lambda x: '{0:1.2f}%'.format(x)),
title=title)
fig.show()
cat_salary, cat_y = "('P2_h ', 'Faixa salarial')", "('P2_g ', 'Nivel')"
cols = [cat_salary, cat_y]
df_temp = df[cols].dropna()
df_temp[cat_salary] = df_temp[cat_salary].apply(
lambda x: x.replace('R$', 'RS') )
plotly_cat_to_cat(
df_temp,
cat_salary, cat_y,
'Faixa Salarial por Nivel',
sort_by_faixa_salarial
)
mapping_faixa_salario_re
{'Menos de RS 1.000/mês': 1,
'de RS 1.001/mês a RS 2.000/mês': 2,
'de RS 2.001/mês a RS 3000/mês': 3,
'de RS 3.001/mês a RS 4.000/mês': 4,
'de RS 4.001/mês a RS 6.000/mês': 5,
'de RS 6.001/mês a RS 8.000/mês': 6,
'de RS 8.001/mês a RS 12.000/mês': 7,
'de RS 12.001/mês a RS 16.000/mês': 8,
'de RS 16.001/mês a RS 20.000/mês': 9,
'de RS 20.001/mês a RS 25.000/mês': 10,
'de RS 25.001/mês a RS 30.000/mês': 11,
'de RS 30.001/mês a RS 40.000/mês': 12,
'Acima de RS 40.001/mês': 13}
import plotly.graph_objects as go
def order_by_salary(x):
return mapping_faixa_salario_re[x]
def plotly_kde_cat_to_cat(df, catx, caty, width=800, title='',
height=500, x_title='',
order_func=None):
# source: https://www.kaggle.com/code/ceruttivini/cientista-ou-analista-de-dados-qual-a-diferen-a
cols = [catx, caty]
df_temp = df.groupby(cols).size().to_frame('count').reindex(
pd.MultiIndex.from_product([df[catx].unique(), df[caty].unique()]), fill_value = 0)
df_temp = df_temp.reset_index().dropna()
df_temp.columns = cols + ['count']
df_temp['percentage'] = get_percentage_complex(df_temp, df, catx)
df_temp['total'] = df_temp['percentage']
df_temp.columns = cols + ['Counts', 'Percentage', 'Total']
if(order_func):
df_temp['ordem'] = df_temp[catx].apply(lambda x: order_func(x))
df_temp = df_temp.sort_values(['ordem', catx])
fig = go.Figure()
caty_values = list(df[caty].unique())
for caty_val in caty_values:
fig.add_trace(go.Scatter(
y = df_temp[df_temp[caty] == caty_val]['Percentage'],
x = df_temp[df_temp[caty] == caty_val][catx],
text = df_temp[df_temp[caty] == caty_val]['Percentage'],
# marker_color = df_temp[df_temp[caty] == caty_val]['Color'].iloc[0],
name = caty_val,
marker_size = 4.5, # tamanho do indicador que fica na linha
textfont_size = 9, # tamanho da fonte dos textos
line_shape='spline', # habilitar linhas suavizadas
line_smoothing=0.8, # % de suavidade aplicada nas linhas
orientation= 'v',
customdata = round(df_temp[df_temp[caty] == caty_val]['Percentage'],2),
hovertemplate= "%{customdata}% - %{x}<extra></extra>"
))
fig.update_layout(
title = '<b>' + title + '</b>',
showlegend=True, # habilitar legenda
plot_bgcolor = "#fff", # cor de fundo
yaxis_showgrid = False, # remoção das linhas dos fundos do eixo y
legend_yanchor="top", # posição da legenda
legend_xanchor="left", # início do espaçamento da legenda
legend_y=1.15, # espaçamento vertical da legenda
legend_x= -0.1, # espaçamento horizontal da legenda
legend_orientation="h", # orientação da legenda
width = width,
height = height,
xaxis_title_text = x_title if x_title else catx, # titulo que fica ao lado do eixo x
xaxis_title_font_color='grey',# cor do título que fica ao lado do eixo x
xaxis_color='grey', # cor do eixo x
yaxis_title_text = 'Percentage', # titulo que fica ao lado do eixo y
yaxis_title_font_color='grey',# cor do título que fica ao lado do eixo y
yaxis_color='grey', # cor do eixo y
yaxis_showticksuffix = 'all', # habilitação de sufixo para eixo y
yaxis_ticksuffix ='%', # adição de "%" na label do eixo y se for porcentagem
)
fig.show()
###################
cat_salary, cat_y = "('P2_h ', 'Faixa salarial')", "('P2_g ', 'Nivel')"
cols = [cat_salary, cat_y]
df_temp = df[cols].dropna()
df_temp[cat_salary] = df_temp[cat_salary].apply(
lambda x: x.replace('R$', 'RS') )
plotly_kde_cat_to_cat(df_temp, cat_salary, cat_y,
title='Faixa Salarial por Senioridade',
x_title='Faixa Salarial',
order_func=order_by_salary)
# Formatando Gestor e Faixa Salarial (replaces e dropna)
df_temp = df[ ["('P2_h ', 'Faixa salarial')", "('P2_d ', 'Gestor?')"] ].dropna().replace({1: 'Sim', 0: 'Não'})
df_temp["('P2_h ', 'Faixa salarial')"] = df_temp["('P2_h ', 'Faixa salarial')"].apply(
lambda x: x.replace('R$', 'RS') )
plotly_cat_to_cat(
df_temp,
"('P2_h ', 'Faixa salarial')", "('P2_d ', 'Gestor?')",
'Faixa Salarial para gestor',
sort_by_faixa_salarial
)
# Formatando Gestor e Faixa Salarial (replaces e dropna)
df_temp = df[ ["('P2_h ', 'Faixa salarial')", "('P2_d ', 'Gestor?')"] ].dropna().replace({1: 'Sim', 0: 'Não'})
df_temp["('P2_h ', 'Faixa salarial')"] = df_temp["('P2_h ', 'Faixa salarial')"].apply(
lambda x: x.replace('R$', 'RS') )
def plotly_cat_to_cat_OLD(df, catx, cat2, title='', orderby_func=None):
"""
Amabas devem ser cat feats
orderby_func = muitas vezes a cat_feat eh ordenavel, use essa campos para designar a funcao
TEM QUE VERIFICAR QUANDO NAO TEM TODAS AS CATEGORIAS, AI DA ERRO
"""
cols = [catx, cat2]
# OLD
df_temp = df.groupby(cols).size().reset_index()
# NEW
# df_temp = df.groupby(cols).size().to_frame('count').reindex(
# pd.MultiIndex.from_product([df[catx].unique(), df[cat2].unique()]), fill_value = 0)
# df_temp = df_temp.reset_index().dropna()
df_temp['percentage'] = df.groupby(cols).size().groupby(level=0).apply(
lambda x: 100 * x / float(x.sum())).values
df_temp['total'] = df_temp['percentage'].apply(int)
df_temp.columns = cols + ['Counts', 'Percentage', 'Total']
# display(df_temp[cat2].value_counts())
# display(df_temp)
fig = px.bar(df_temp, x=catx, y=['Total'], color=cat2,
category_orders=orderby_func, hover_data=['Counts'],
text=df_re['Percentage'].apply(lambda x: '{0:1.2f}%'.format(x)), title=title)
fig.show()
# plotly_cat_to_cat_OLD(
# df_temp,
# "('P2_h ', 'Faixa salarial')", "('P2_d ', 'Gestor?')",
# 'Faixa Salarial para gestor',
# sort_by_faixa_salarial
# )
df_temp = df[ ["('P2_h ', 'Faixa salarial')",
"('P2_i ', 'Quanto tempo de experiência na área de dados você tem?')"] ]
df_temp = df_temp.dropna()
df_temp["('P2_h ', 'Faixa salarial')"] = df_temp["('P2_h ', 'Faixa salarial')"].apply(lambda x: str(x).replace('R$', 'RS') )
df_temp = df_temp.rename(columns={
"('P2_i ', 'Quanto tempo de experiência na área de dados você tem?')":
"Tempo na área de Dados"})
df_temp = df_temp.replace({'Não tenho experiência na área de dados': 'Sem EXP'})
plotly_cat_to_cat(
df_temp,
"('P2_h ', 'Faixa salarial')",
"Tempo na área de Dados",
'Faixa Salarial pelo Tempo na área de Dados (Use o Filtro)',
sort_by_faixa_salarial
)
# "('P2_i ', 'Quanto tempo de experiência na área de dados você tem?')" "('P2_f ', 'Cargo Atual')"
main_jobs = ['Cientista de Dados/Data Scientist',
'Analista de BI/BI Analyst/Analytics Engineer',
'Analista de Dados/Data Analyst',
'Engenheiro de Dados/Data Engineer']
df_temp = df[ ["('P2_h ', 'Faixa salarial')", "('P2_f ', 'Cargo Atual')"] ].dropna()
df_temp = df_temp[ df_temp["('P2_f ', 'Cargo Atual')"].isin(main_jobs) ]
df_temp['Ordem'] = df_temp["('P2_h ', 'Faixa salarial')"].apply(lambda x: mapping_faixa_salario[x])
df_temp["('P2_h ', 'Faixa salarial')"] = df_temp["('P2_h ', 'Faixa salarial')"].apply(lambda x: x.replace('R$', 'RS') )
# plotly_cat_to_cat(
# df_temp,
# "('P2_h ', 'Faixa salarial')",
# "('P2_f ', 'Cargo Atual')",
# 'Faixa Salarial nas 4 principais prosissoes de dados',
# sort_by_faixa_salarial
# )
plotly_kde_cat_to_cat(df_temp,
"('P2_h ', 'Faixa salarial')",
"('P2_f ', 'Cargo Atual')",
title='Faixa Salarial por Cargo',
x_title='Faixa Salarial',
height=600,
order_func=order_by_salary)
print(df["('P2_g ', 'Nivel')"].unique())
print()
print(df["('P2_f ', 'Cargo Atual')"].unique())
print()
print(df["('P2_a ', 'Qual sua situação atual de trabalho?')"].unique())
[nan 'Sênior' 'Pleno' 'Júnior'] [nan 'Engenheiro de Dados/Data Engineer' 'Cientista de Dados/Data Scientist' 'Técnico' 'Analista de BI/BI Analyst/Analytics Engineer' 'Analista de Negócios/Business Analyst' 'Analista de Marketing' 'Analista de Dados/Data Analyst' 'Desenvolvedor ou Engenheiro de Software' 'Analista Administrativo' 'Engenheiro de Machine Learning/ML Engineer' 'Outras Engenharias (não inclui dev)' 'DBA/Administrador de Banco de Dados' 'Outro' 'Professor' 'Estatístico' 'Analista de Sistemas/Analista de TI' 'Analista de Inteligência de Mercado/Market Intelligence' 'Arquiteto de Dados' 'Suporte Técnico' 'Arquiteto de dados' 'Product Manager'] ['Empregado (CLT)' 'Empreendedor ou Empregado (CNPJ)' 'Servidor Público' 'Estagiário' 'Freelancer' 'Prefiro não informar' 'Vivo no Brasil e trabalho remoto para empresa de fora do Brasil (PJ)' 'Vivo fora do Brasil e trabalho para empresa de fora do Brasil' 'Trabalho na área Acadêmica/Pesquisador' 'Somente Estudante (graduação)' 'Desempregado, buscando recolocação' 'Somente Estudante (pós-graduação)' 'Desempregado e não estou buscando recolocação']
def bar_plotly_cat_feat(adf, col, title='', x_col_rename=''):
"""
Cria BarPlotly usando Value counts de uma Series cat-feat
"""
# Define Constants
qtd_col = 'Quantidade' # pode ser mudado para 'count'
percentage_col = 'Porcentagem' # pode ser mudado para 'percent'
x_col = x_col_rename if x_col_rename else col
# Pre-Processing
df_temp = adf[col].value_counts().reset_index().rename(
columns={'index': x_col, col: qtd_col}
)
# Col Percentage in String
df_temp[percentage_col] = round(
(df_temp[qtd_col] / df_temp[qtd_col].sum()) * 100.0, 2).apply(
lambda x: str(format(x,'.2f')) + '%' )
# BarPlotly Figure
fig = px.bar(
df_temp, y=qtd_col, x=x_col,
color=qtd_col, hover_data=[percentage_col],
text=percentage_col, title=title,
color_continuous_scale='dense'
)
fig.show()
def bar_plotly_describe_cat_feat_filter_cat_feats_values(adf, x_feat, adict, start_title='', x_col_rename=''):
"""
Filtra dataframe por hard-code de cat-feats. Em seguida aplica barPlotlyOneCatFeat.
O titulo é feito por uma base inicial e em sequencia concatenações dos valores usados
"""
# Filter DataFrame by values of cat feats
df_temp, title = adf, start_title
for col in adict.keys():
df_temp = df_temp[ df_temp[col] == adict[col] ]
title = title + ' - ' + adict[col]
# Bar PLotly One Cat Feat
bar_plotly_cat_feat(df_temp, x_feat, title, x_col_rename)
adict = {
"('P2_f ', 'Cargo Atual')": 'Engenheiro de Dados/Data Engineer',
"('P2_g ', 'Nivel')": 'Pleno',
"('P2_a ', 'Qual sua situação atual de trabalho?')": 'Empregado (CLT)',
}
bar_plotly_describe_cat_feat_filter_cat_feats_values(
df,
"('P2_h ', 'Faixa salarial')",
adict=adict,
start_title='Faixa Salarial de',
x_col_rename='Faixa Salarial',
)
def bar_plotly_multiple_filters_to_salary(
adf, nivel='', cargo='',
exp='', job_type='', exp_data=''):
df_temp = adf
df_temp = df_temp[ df_temp["('P2_g ', 'Nivel')"] == nivel] if nivel else df_temp
df_temp = df_temp[ df_temp["('P2_f ', 'Cargo Atual')" ] == cargo] if cargo else df_temp
df_temp = df_temp[ df_temp["('P2_a ', 'Qual sua situação atual de trabalho?')"] == job_type] if job_type else df_temp
df_temp = df_temp[ df_temp["('P2_i ', 'Quanto tempo de experiência na área de dados você tem?')"] == exp_data] if exp_data else df_temp
title = 'Faixa Salarial '
title = title + ' - ' + nivel if nivel else title
title = title + ' - ' + cargo if cargo else title
title = title + ' - ' + job_type if job_type else title
title = title + ' - ' + exp_data if exp_data else title
cols = []
cols.append("('P2_g ', 'Nivel')") if nivel else cols
cols.append("('P2_f ', 'Cargo Atual')") if cargo else cols
cols.append("('P2_a ', 'Qual sua situação atual de trabalho?')") if job_type else cols
cols.append("('P2_i ', 'Quanto tempo de experiência na área de dados você tem?')") if exp_data else cols
df_temp = df_temp["('P2_h ', 'Faixa salarial')"].value_counts().reset_index()
df_temp = df_temp.rename(columns={'index': 'Faixa salarial', "('P2_h ', 'Faixa salarial')": "Quantidade"})
df_temp['Faixa salarial'] = df_temp['Faixa salarial'].apply(lambda x: x.replace('R$', 'RS'))
df_temp['Ordem'] = df_temp["Faixa salarial"].apply(lambda x: mapping_faixa_salario_re[x])
df_temp['Porcentagem'] = round( (df_temp['Quantidade'] / df_temp['Quantidade'].sum()) * 100.0, 2)
df_temp['PorcentagemStr'] = df_temp['Porcentagem'].apply(lambda x: str(format(x, '.2f')) + '%' )
df_temp = df_temp.sort_values('Ordem')
fig = px.bar(
df_temp, y='Quantidade', x='Faixa salarial',
color='Quantidade', hover_data=['PorcentagemStr'],
text="PorcentagemStr", title=title,
color_continuous_scale='dense'
)
fig.show()
bar_plotly_multiple_filters_to_salary(
df, nivel='Pleno')
bar_plotly_multiple_filters_to_salary(
df,
nivel='Pleno',
cargo='Engenheiro de Dados/Data Engineer',
)
bar_plotly_multiple_filters_to_salary(
df,
job_type='Estagiário',
)
bar_plotly_multiple_filters_to_salary(
df,
cargo='Engenheiro de Dados/Data Engineer',
job_type='Estagiário',
)
def bar_plotly_cat_feat_sorted(adf, col, title='', x_col_rename=''):
"""
Cria BarPlotly usando Value counts de uma Series cat-feat
"""
# Define Constants
qtd_col = 'Quantidade' # pode ser mudado para 'count'
percentage_col = 'Porcentagem' # pode ser mudado para 'percent'
x_col = x_col_rename if x_col_rename else col
# Pre-Processing
df_temp = adf[col].value_counts().reset_index().rename(
columns={'index': x_col, col: qtd_col}
)
df_temp = df_temp.sort_values(x_col)
# Col Percentage in String
df_temp[percentage_col] = round(
(df_temp[qtd_col] / df_temp[qtd_col].sum()) * 100.0, 2).apply(
lambda x: str(format(x,'.2f')) + '%' )
# BarPlotly Figure
fig = px.bar(
df_temp, y=qtd_col, x=x_col,
color=qtd_col, hover_data=[percentage_col],
text=percentage_col, title=title,
color_continuous_scale='dense'
)
fig.show()
cargo_temp = 'Cientista de Dados/Data Scientist'
nivel_temp = 'Júnior'
df_queryed = df[ df["('P2_f ', 'Cargo Atual')"] == 'Cientista de Dados/Data Scientist' ]
df_queryed = df_queryed[ df_queryed["('P2_g ', 'Nivel')"] == 'Júnior']
super_title = 'Cientista de Dados Júnior'
bar_plotly_cat_feat_sorted(
df_queryed,
"('P1_a_a ', 'Faixa idade')",
super_title + ' - Faixa de Idade',
'Faixa de Idade',
)
bar_plotly_cat_feat(
df_queryed,
"('P1_h ', 'Nivel de Ensino')",
super_title + ' - Nivel de Ensino',
'Nivel de Ensino',
)
bar_plotly_cat_feat(
df_queryed,
"('P2_k ', 'Você está satisfeito na sua empresa atual?')",
super_title + ' - Satisfeito',
'Satisfeito',
)
bar_plotly_multiple_filters_to_salary(
df_queryed,
nivel=nivel_temp,
cargo=cargo_temp,
)
df["('P2_q ', 'Atualmente qual a sua forma de trabalho?')"].unique()
array(['Modelo 100% presencial',
'Modelo híbrido flexível (o funcionário tem liberdade para escolher quando estar no escritório presencialmente)',
'Modelo híbrido com dias fixos de trabalho presencial',
'Modelo 100% remoto', nan], dtype=object)
bar_plotly_cat_feat(
df_queryed.replace(
{'Modelo híbrido flexível (o funcionário tem liberdade para escolher quando estar no escritório presencialmente)':
'Modelo Flexivel'
}
),
"('P2_q ', 'Atualmente qual a sua forma de trabalho?')",
super_title + ' - Forma de Trabalho',
'Forma de Trabalho',
)
bar_plotly_cat_feat(
df_queryed.replace(
{'Modelo híbrido flexível (o funcionário tem liberdade para escolher quando estar no escritório presencialmente)':
'Modelo Flexivel'
}
),
"('P2_r ', 'Qual a forma de trabalho ideal para você?')",
super_title + ' - Forma de trabalho ideal',
'Forma de trabalho ideal',
)
def generate_dict_to_p4_anwer(alist):
return {
'prefix': alist[0],
'temp_name_col': alist[1],
'title': alist[2],
}
sufix = ' - Cientista de Dados Júnior'
p4_answers = {
"('P4_b ', 'Quais das fontes de dados listadas você já analisou ou processou no trabalho?')":
generate_dict_to_p4_anwer(["('P4_b_", 'Fontes de dados Usadas',
'Fontes de dados que já analisou' + sufix ]),
"('P4_c ', 'Entre as fontes de dados listadas, quais você utiliza na maior parte do tempo?')":
generate_dict_to_p4_anwer(["('P4_c_", 'Fontes de que mais usa',
'Fontes de dados que mais usa' + sufix ]),
"('P4_d ', 'Quais das linguagens listadas abaixo você utiliza no trabalho?')":
generate_dict_to_p4_anwer(["('P4_d_", 'Linguages',
'Linguagesn que mais utiliza' + sufix ]),
"('P4_e ', 'Entre as linguagens listadas abaixo, qual é a que você mais utiliza no trabalho?')":
generate_dict_to_p4_anwer(["('P4_e_", 'Linguagem mais utilizada',
'Linguagem mais utilizada' + sufix ]),
"('P4_f ', 'Quais dos bancos de dados/fontes de dados listados abaixo você utiliza no trabalho?')":
generate_dict_to_p4_anwer(["('P4_f_", 'BD utilizados',
'Banco de Dados utilizados' + sufix ]),
"('P4_g ', 'Quais das opções de Cloud listadas abaixo você utiliza no trabalho?')":
generate_dict_to_p4_anwer(["('P4_g_", 'Cloud usados',
'Cloud usados' + sufix ]),
"('P4_h ', 'Quais as Ferramentas de Business Intelligence você utiliza no trabalho?')":
generate_dict_to_p4_anwer(["('P4_h_", 'Ferramenta de BI',
'Ferramenta de BI' + sufix ]),
}
for key, value in p4_answers.items():
bar_plot_many_options(
df_queryed,
prefix=value['prefix'],
temp_name_col=value['temp_name_col'],
true_count=count_valid_values(df_queryed[key]),
title=value['title'],
)
def generate_dict_to_p8_answer(alist):
return {
'prefix': alist[0],
'temp_name_col': alist[1],
'title': alist[2],
'break_line': len(alist) == 4
}
sufix = ' - Cientista de Dados Júnior'
p8_answers = {
"('P8_a ', 'Quais das opções abaixo fazem parte da sua rotina no trabalho atual com ciência de dados?')":
generate_dict_to_p8_answer(["('P8_a_", 'Rotinas no Trabalho de Ciencia de dados',
'Rotinas no Trabalho de Ciencia de dados' + sufix, True ]),
"('P8_b ', 'Quais as técnicas e métodos listados abaixo você costuma utilizar no trabalho?')":
generate_dict_to_p8_answer(["('P8_b_", 'Técnicas e Métodos utilizados',
'Técnicas e Métodos utilizados' + sufix, True ]),
"('P8_c ', 'Quais dessas tecnologias fazem parte do seu dia a dia como cientista de dados?')":
generate_dict_to_p8_answer(["('P8_c_", 'Tecnologias usadas no dia-a-dia',
'Tecnologias usadas no dia-a-dia' + sufix, True ]),
"('P8_d ', 'Em qual das opções abaixo você gasta a maior parte do seu tempo no trabalho?')":
generate_dict_to_p8_answer(["('P8_d_", 'Rotina que mais gasta tempo',
'Rotina que mais gasta tempo' + sufix, True ]),
}
for key, value in p8_answers.items():
bar_plot_many_options(
df_queryed,
prefix=value['prefix'],
temp_name_col=value['temp_name_col'],
true_count=count_valid_values(df_queryed[key]),
title=value['title'],
break_line=value['break_line']
)
cargo_temp = 'Engenheiro de Dados/Data Engineer'
nivel_temp = 'Júnior'
df_queryed = df[ df["('P2_f ', 'Cargo Atual')"] == cargo_temp ]
df_queryed = df_queryed[ df_queryed["('P2_g ', 'Nivel')"] == nivel_temp]
super_title = 'Engenheiro de Dados Júnior'
bar_plotly_cat_feat_sorted(
df_queryed,
"('P1_a_a ', 'Faixa idade')",
super_title + ' - Faixa de Idade',
'Faixa de Idade',
)
bar_plotly_cat_feat(
df_queryed,
"('P1_h ', 'Nivel de Ensino')",
super_title + ' - Nivel de Ensino',
'Nivel de Ensino',
)
bar_plotly_cat_feat(
df_queryed,
"('P2_k ', 'Você está satisfeito na sua empresa atual?')",
super_title + ' - Satisfeito',
'Satisfeito',
)
bar_plotly_multiple_filters_to_salary(
df_queryed,
nivel=nivel_temp,
cargo=cargo_temp,
)
bar_plotly_cat_feat(
df_queryed.replace(
{'Modelo híbrido flexível (o funcionário tem liberdade para escolher quando estar no escritório presencialmente)':
'Modelo Flexivel'
}
),
"('P2_q ', 'Atualmente qual a sua forma de trabalho?')",
super_title + ' - Forma de Trabalho',
'Forma de Trabalho',
)
bar_plotly_cat_feat(
df_queryed.replace(
{'Modelo híbrido flexível (o funcionário tem liberdade para escolher quando estar no escritório presencialmente)':
'Modelo Flexivel'
}
),
"('P2_r ', 'Qual a forma de trabalho ideal para você?')",
super_title + ' - Forma de trabalho ideal',
'Forma de trabalho ideal',
)
def generate_dict_to_p6_answer(alist):
return {
'prefix': alist[0],
'temp_name_col': alist[1],
'title': alist[2],
}
sufix = ' - Engenheiro de Dados Júnior'
p6_answers = {
"('P6_a ', 'Quais das opções abaixo fazem parte da sua rotina no trabalho atual como engenheiro de dados?')":
generate_dict_to_p8_answer(["('P6_a_", 'Rotina de DE',
'Rotinas de Engenheiro de Dados' + sufix, True ]),
"('P6_b ', 'Quais as ferramentas/tecnologias de ETL que você utiliza no trabalho como Data Engineer?')":
generate_dict_to_p8_answer(["('P6_b_", 'Ferramentas de ETL para Data Engineer',
'Ferramentas de ETL utilizadas por DataEngineerers' + sufix ]),
"('P6_g ', 'Quais as ferramentas de gestão de Qualidade de dados, Metadados e catálogo de dados você utiliza no trabalho?')":
generate_dict_to_p8_answer(["('P6_g_", 'Ferramentas de qualidade de dados para Data Engineer',
'Ferramentas de qualidade de dados para Data Engineer' + sufix ]),
"('P6_h ', 'Em qual das opções abaixo você gasta a maior parte do seu tempo?')":
generate_dict_to_p8_answer(["('P6_h_", 'Rotinas que mais gastam tempo',
'Rotinas que mais gastam tempo' + sufix, True ]),
}
for key, value in p6_answers.items():
bar_plot_many_options(
df_queryed,
prefix=value['prefix'],
temp_name_col=value['temp_name_col'],
true_count=count_valid_values(df_queryed[key]),
title=value['title'],
break_line=value['break_line']
)
def generate_dict_to_answer(alist):
return {
'suffix': alist[0],
'x_rename_col': alist[1],
}
dict_cols ={
"('P6_c ', 'Sua organização possui um Data Lake?')":
generate_dict_to_answer(['Tem DataLake', "A Organizaçao tem datalake?"]),
"('P6_d ', 'Qual tecnologia utilizada como plataforma do Data Lake?')":
generate_dict_to_answer(['Tec usada no Datalake', "Tec de Datalake"]),
"('P6_e ', 'Sua organização possui um Data Warehouse?')":
generate_dict_to_answer(['Tem DataWarehouse (DW)?', "Tem DW"]),
"('P6_f ', 'Qual tecnologia utilizada como plataforma do Data Warehouse?')":
generate_dict_to_answer(['Tecnologia usada do DW', "Tec de DW"]),
}
for key, value in dict_cols.items():
bar_plotly_cat_feat(
df_queryed,
key,
super_title + ' -' + value['suffix'],
value['x_rename_col']
)
cargo_temp = 'Analista de Dados/Data Analyst'
nivel_temp = 'Júnior'
df_queryed = df[ df["('P2_f ', 'Cargo Atual')"] == cargo_temp ]
df_queryed = df_queryed[ df_queryed["('P2_g ', 'Nivel')"] == nivel_temp]
super_title = 'Analista de Dados Júnior'
bar_plotly_cat_feat_sorted(
df_queryed,
"('P1_a_a ', 'Faixa idade')",
super_title + ' - Faixa de Idade',
'Faixa de Idade',
)
bar_plotly_cat_feat(
df_queryed,
"('P1_h ', 'Nivel de Ensino')",
super_title + ' - Nivel de Ensino',
'Nivel de Ensino',
)
bar_plotly_cat_feat(
df_queryed,
"('P2_k ', 'Você está satisfeito na sua empresa atual?')",
super_title + ' - Satisfeito',
'Satisfeito',
)
bar_plotly_multiple_filters_to_salary(
df_queryed,
nivel=nivel_temp,
cargo=cargo_temp,
)
bar_plotly_cat_feat(
df_queryed.replace(
{'Modelo híbrido flexível (o funcionário tem liberdade para escolher quando estar no escritório presencialmente)':
'Modelo Flexivel'
}
),
"('P2_q ', 'Atualmente qual a sua forma de trabalho?')",
super_title + ' - Forma de Trabalho',
'Forma de Trabalho',
)
bar_plotly_cat_feat(
df_queryed.replace(
{'Modelo híbrido flexível (o funcionário tem liberdade para escolher quando estar no escritório presencialmente)':
'Modelo Flexivel'
}
),
"('P2_r ', 'Qual a forma de trabalho ideal para você?')",
super_title + ' - Forma de trabalho ideal',
'Forma de trabalho ideal',
)
sufix = ' - Analista de Dados Júnior'
p7_answers = {
"('P7_a ', 'Quais das opções abaixo fazem parte da sua rotina no trabalho atual com análise de dados?')":
generate_dict_to_p8_answer(["('P7_a_", 'Rotina de DA',
'Rotinas de Analista de Dados' + sufix, True ]),
"('P7_b ', 'Quais as ferramentas/tecnologias de ETL que você utiliza no trabalho como Data Analyst?')":
generate_dict_to_p8_answer(["('P7_b_", 'Ferramentas de ETL para Data Analyst',
'Ferramentas de ETL utilizadas por DataAnalyse' + sufix ]),
"('P7_c ', 'Sua empresa utiliza alguma das ferramentas listadas para dar mais autonomia em análise de dados para as áreas de negócio?')":
generate_dict_to_p8_answer(["('P7_c_", 'Ferramentas de analise automatica de dados',
'Ferramentas de analise automatica de dados' + sufix, True ]),
"('P7_d ', 'Em qual das opções abaixo você gasta a maior parte do seu tempo de trabalho?')":
generate_dict_to_p8_answer(["('P7_d_", 'Rotinas que mais gastam tempo',
'Rotinas que mais gastam tempo para DA' + sufix, True ]),
}
for key, value in p7_answers.items():
bar_plot_many_options(
df_queryed,
prefix=value['prefix'],
temp_name_col=value['temp_name_col'],
true_count=count_valid_values(df_queryed[key]),
title=value['title'],
break_line=value['break_line']
)
def plotly_scatter_polar(df, catx, x_vals, caty, y_vals, title, range_=100):
"""
Faz ScatterPolar de cat com cat, escolhendo cat values de X com y
range eh tamanho do angulo, deve ser regulado para cada grafico em particular apos ver como fica em 100
"""
# source: https://www.kaggle.com/code/ceruttivini/cientista-ou-analista-de-dados-qual-a-diferen-a
adict_dfs = {}
for xval in x_vals:
df_start = df[ df[catx] == xval]
df_aux = df_start[caty].value_counts().reset_index().rename(
columns={'index': caty, caty: 'count'})
df_aux['percent'] = 100 * (df_aux['count'] / df_start[caty].count())
df_aux = df_aux[ df_aux[caty].isin(y_vals) ]
# para fazer um contorno no formato de círculo é necessário
# fazer a inclusão do primeiro valor como último
df_aux = df_aux.append(df_aux.iloc[0,:])
adict_dfs[xval] = df_aux
fig = go.Figure()
for key, value in adict_dfs.items():
fig.add_trace(go.Scatterpolar(
r=value['percent'],
theta=value[caty],
name=key,
mode='lines',
line_shape='spline',
line_smoothing=0.8,
marker_size = 9.5, # tamanho dos indicadores das linhas (bolinhas)
line_width=1.6, # grossura da linha da resposta,
showlegend = True, # showlegend and len(self.polar_layout)+1 < 2, # opção de adicionar legenda para cada linha
hoverinfo='r+theta+name', # padrão quando passar o mouse em cima
customdata = value['count'],
hovertemplate='%{r:0.0f}%<br>%{theta}<br>%{customdata}'
))
fig_polar_layout = {
"bgcolor":"white", # cor de fundo
"radialaxis_visible":True, # apresentação da grid
"radialaxis_showticklabels":True, # apresentação de texto da grid
"radialaxis_tickfont_color":"darkgrey", # cor do texto da grid
"radialaxis_layer":"below traces", # se a linha passa os pontos ou nao
"radialaxis_gridcolor":"#d9d7d7", # cor da grid
"radialaxis_tickangle": -350, # angular da label da grid
"radialaxis_range":(0,range_),# intervalo da grid
"radialaxis_tickvals":list(range(10,range_,10)),# intervalo do texto grid
"radialaxis_ticktext":[ f"{t}%" if t % 20 == 0 else "" for t in range(10,range_,10)], # texto da grid
"radialaxis_tickfont_size" : 10, # fonte da grid
"angularaxis_tickfont_size" : 14} # fonte das opções de resposta
fig.update_layout(
title=title,
polar=fig_polar_layout,
width = 900, # chart size
height = 450 # chart size
)
fig.show()
x_col = "('P2_f ', 'Cargo Atual')"
x_vals = ['Cientista de Dados/Data Scientist',
'Analista de BI/BI Analyst/Analytics Engineer',
'Analista de Dados/Data Analyst',
'Engenheiro de Dados/Data Engineer']
y_col = "('P4_e ', 'Entre as linguagens listadas abaixo, qual é a que você mais utiliza no trabalho?')"
y_vals = ['Python', 'SQL', 'R', 'Java', 'Scala']
plotly_scatter_polar(df, x_col, x_vals, y_col, y_vals, 'Linguagens por Cargos', 85)
def my_heatmap_plot(
z, x, y, escala_cor, titulo, yaxis_titulo,
xaxis_titulo, largura = 700, altura= 450, pct=False, order_list_x_axis=None):
"""
Método que constrói um gráfico/tabela em mapa de calor
Parâmetros:
----------
z: valores para z (eixo z = valor = cor)
x: valores para x (eixo x = cat values)
y: valores para y (eixo y = cat values)
escala_cor: uma lista com escala de cores para degrade
titulo: título do gráfico
yaxis_titulo: titulo para ficar ao lado do eixo y
xaxis_titulo: titulo para ficar ao lado do eixo x
largura: largura do gráfico
altura: altura do gráfico
pct: se os valores são porcentagem, desta forma já adiciona "%" nos textos
"""
fig = go.Figure()
fig.add_trace(go.Heatmap(
z = z,
x = x,
y = y,
text = z.apply(lambda col: self.porcentagem_texto(col)) if pct else z, # texto para ser apresentado se for porcentagem, converter para porcentagem
texttemplate = "%{text}",
ygap = 1, # adição de uma linha em volta dos quadrados
xgap = 1, # adição de uma linha em volta dos quadrados
colorscale = escala_cor, # degrade para se realizar de acordo com os valores
showscale = False, # remover a imagem de escala ao lado do gráfico
hovertemplate= "%{x}<br>%{y}<br>%{text}<extra></extra>"
))
fig.update_layout(
title= titulo,
# xaxis_tickangle = 0, # deixar as labels (ticks) do eixo x horizontalmente
width = largura,
height = altura,
yaxis_title_text = yaxis_titulo,
xaxis_title_text = xaxis_titulo,
xaxis_title_font_color='grey',# cor da fonte do título eixo X
yaxis_title_font_color='grey',# cor da fonte do título eixo y
# yaxis_tickfont_size = 12, # tamanho da fonte para labels (ticks) do eixo y
# xaxis_tickfont_size = 12, # tamanho da fonte para labels (ticks) do eixo x
xaxis_color='grey',# cor das labels (ticks) do eixo X
yaxis_color='grey' # cor das labels (ticks) do eixo y
)
fig.show()
def plotly_heatmap_cat_feats(
df, catx, caty, title, escala_cor=None, yaxis_titulo=None,
xaxis_titulo=None, largura = 700, altura= 450, pct=False,
order_list_x_axis=None):
"""
Método que constrói um gráfico/tabela em mapa de calor
Parâmetros:
----------
z: valores para z (eixo z = valor = cor)
x: valores para x (eixo x = cat values)
y: valores para y (eixo y = cat values)
escala_cor: uma lista com escala de cores para degrade
titulo: título do gráfico
yaxis_titulo: titulo para ficar ao lado do eixo y
xaxis_titulo: titulo para ficar ao lado do eixo x
largura: largura do gráfico
altura: altura do gráfico
pct: se os valores são porcentagem, desta forma já adiciona "%" nos textos
"""
# Pre processing
dft = df[ [catx, caty] ]
dft = dft.groupby([catx,caty]).size().reset_index()
dft.columns = ['catx', 'caty', 'values']
dft = pd.pivot_table(
dft, values='values', index='caty',
columns='catx', aggfunc=np.sum, fill_value=0)
if(order_list_x_axis):
dft = dft[order_list_x_axis]
fig = go.Figure()
fig.add_trace(go.Heatmap(
z = dft,
x = dft.columns.tolist(),
y = dft.index.tolist(),
# texto para ser apresentado se for porcentagem, converter para porcentagem
text = dft.apply(lambda col: self.porcentagem_texto(col)) if pct else dft,
texttemplate = "%{text}",
ygap = 1, # adição de uma linha em volta dos quadrados
xgap = 1, # adição de uma linha em volta dos quadrados
# degrade para se realizar de acordo com os valores
colorscale = escala_cor if escala_cor else px.colors.sequential.Blues,
showscale = False, # remover a imagem de escala ao lado do gráfico
hovertemplate= "%{x}<br>%{y}<br>%{text}<extra></extra>"
))
fig.update_layout(
title= title,
# xaxis_tickangle = 0, # deixar as labels (ticks) do eixo x horizontalmente
width = largura,
height = altura,
yaxis_title_text = yaxis_titulo if yaxis_titulo else caty,
xaxis_title_text = xaxis_titulo if xaxis_titulo else catx,
xaxis_title_font_color='grey',# cor da fonte do título eixo X
yaxis_title_font_color='grey',# cor da fonte do título eixo y
# yaxis_tickfont_size = 12, # tamanho da fonte para labels (ticks) do eixo y
# xaxis_tickfont_size = 12, # tamanho da fonte para labels (ticks) do eixo x
xaxis_color='grey',# cor das labels (ticks) do eixo X
yaxis_color='grey' # cor das labels (ticks) do eixo y
)
fig.show()
catx = "('P2_i ', 'Quanto tempo de experiência na área de dados você tem?')"
caty = "('P2_g ', 'Nivel')"
true_order = [
'Não tenho experiência na área de dados',
'Menos de 1 ano',
'de 1 a 2 anos',
'de 2 a 3 anos',
'de 4 a 5 anos',
'de 6 a 10 anos',
'Mais de 10 anos',
]
plotly_heatmap_cat_feats(
df, catx, caty, title='Exp em Dados por Nível',
order_list_x_axis=true_order
)
df["('P2_h ', 'Faixa salarial')"] = df["('P2_h ', 'Faixa salarial')"].apply(
lambda x: x if not x else str(x).replace('$','S'))
plotly_heatmap_cat_feats(
df,
"('P2_h ', 'Faixa salarial')",
"('P2_g ', 'Nivel')",
title='Exp em Dados por Nível',
order_list_x_axis=mapping_faixa_salario_re.keys()
)